
#include "string.h"

#include "jxos_public.h"

#include <srtnet_config.h>

#include "../communication_layer/transmitter.h"
#include "../communication_layer/receiver.h"
#include "../communication_layer/communication_layer_frame.h"

#include "application_layer_binding_table.h"
#include "application_layer_service.h"
#include "service_define.h"

#if (SRTNET_COMM_DEVICE_TYPE == SRTNET_COMM_DEVICE_TYPE_RECEIVER)\
    ||(SRTNET_COMM_DEVICE_TYPE == SRTNET_COMM_DEVICE_TYPE_REPEATER)
static JXOS_EVENT_HANDLE event_app_rec_ok;

static uint16_t master_addr;
static uint8_t master_service_serila_num;
static uint8_t master_service_id;
static uint8_t master_service_cmd_id;
static uint8_t master_service_rec_cmd_param_len;
static uint8_t master_service_rec_cmd_param[SERVICE_CMD_PARAME_LEN_MAX];

static void srtnet_app_task(uint8_t task_id, void * parameter)
{
	uint8_t slave_service_serila_num;
	if(jxos_event_wait(event_app_rec_ok) == 1){
#if (SRTNET_APP_LAYER_DEBUG_PRINT_ENABLE == 1)
		sys_debug_print_task_user_print_str("srtapp snum: ");
		sys_debug_print_task_user_print_uint(master_service_serila_num);
		sys_debug_print_task_user_print_str("\r\n");

		sys_debug_print_task_user_print_str("srtapp sid: ");
		sys_debug_print_task_user_print_uint(master_service_id);
		sys_debug_print_task_user_print_str("\r\n");

		sys_debug_print_task_user_print_str("srtapp cmd: ");
		sys_debug_print_task_user_print_uint(master_service_cmd_id);
		sys_debug_print_task_user_print_str("\r\n");

		sys_debug_print_task_user_print_str("srtapp param: ");
		sys_debug_print_task_user_print_data_stream_in_hex(master_service_rec_cmd_param, master_service_rec_cmd_param_len);
		sys_debug_print_task_user_print_str("\r\n");
#endif
		if(master_addr == ADDR_BROADCAST){
			if(master_service_serila_num < DEFAULT_SERVICE_SERILA_NUM_START){
				return;
			}
			slave_service_serila_num = master_service_serila_num;
			srtnet_app_layer_service_slave_receive_cmd_handler(slave_service_serila_num,
															master_service_id, master_service_cmd_id,
															master_service_rec_cmd_param);
		}
		else{
			srtnet_app_layer_binding_table_lookup_reset();
			while(1){
				if(srtnet_app_layer_binding_table_lookup(master_addr, master_service_serila_num, 
						master_service_id, &slave_service_serila_num) == 1){
					if(slave_service_serila_num >= DEFAULT_SERVICE_SERILA_NUM_START){
						break;
					}
					if((service_config_table[slave_service_serila_num][SERVICE_CONFIG_TABLE_SERVICE_ID_OBJECT] != master_service_id)
					||(service_config_table[slave_service_serila_num][SERVICE_CONFIG_TABLE_SERVICE_M_S_OBJECT] != SERVICE_SLAVE)){
						break;
					}
					srtnet_app_layer_service_slave_receive_cmd_handler(slave_service_serila_num,
																	master_service_id, master_service_cmd_id,
																	master_service_rec_cmd_param);
				}
				else{
					break;
				}
			}
		}
	}
}

static void srtnet_app_layer_data_receive_handler(SRTNET_COMM_REC_DATA_STRUCT* receive_playload_s)
{
	master_addr = receive_playload_s->source_node_addr;
	master_service_rec_cmd_param_len = 	(receive_playload_s->receive_playload[0]>>5);
	master_service_id = 				receive_playload_s->receive_playload[0]&0x1f;
	master_service_cmd_id = 			(receive_playload_s->receive_playload[1]>>4);
	master_service_serila_num = 		receive_playload_s->receive_playload[1]&0x0f;
	memcpy(master_service_rec_cmd_param, &(receive_playload_s->receive_playload[2]), (master_service_rec_cmd_param_len+1));
#if (SRTNET_APP_LAYER_DEBUG_PRINT_ENABLE == 1)
	sys_debug_print_task_user_print_str("srtapp rec: ");
	sys_debug_print_task_user_print_data_stream_in_hex(receive_playload_s->receive_playload, receive_playload_s->receive_playload_len);
	sys_debug_print_task_user_print_str("\r\n");
#endif
	jxos_event_set(event_app_rec_ok);
}
#endif

void srtnet_app_layer_task_init(void)
{
#if (SRTNET_COMM_DEVICE_TYPE == SRTNET_COMM_DEVICE_TYPE_RECEIVER)\
    ||(SRTNET_COMM_DEVICE_TYPE == SRTNET_COMM_DEVICE_TYPE_REPEATER)
	srtnet_app_layer_binding_table_recover();
	
	if(SERVICE_CONFIG_TABLE_LEN >= DEFAULT_SERVICE_SERILA_NUM_START){
#if (SRTNET_APP_LAYER_DEBUG_PRINT_ENABLE == 1)
		sys_debug_print_task_blocked_print_str(__FILE__);
		sys_debug_print_task_blocked_print_str(" at line: ");
		sys_debug_print_task_blocked_print_uint(__LINE__ -4);
		sys_debug_print_task_blocked_print_str("\r\nERROR!! SERVICE_CONFIG_TABLE_LEN must less then DEFAULT_SERVICE_SERILA_NUM_START ");
		sys_debug_print_task_blocked_print_uint(DEFAULT_SERVICE_SERILA_NUM_START);
		sys_debug_print_task_blocked_print_str("\r\n");
#endif
		while(1);
	}

	memset(master_service_rec_cmd_param, 0, SERVICE_CMD_PARAME_LEN_MAX);
	srtnet_comm_layer_receiver_device_indication_data_receive = srtnet_app_layer_data_receive_handler;
	jxos_task_create(srtnet_app_task, "srtnet_app", 0);
	event_app_rec_ok = jxos_event_create();
#endif
}
